package ie.dkit.semanticPhotoWeb.server.clientServerConnector;

import ie.dkit.semanticPhotoWeb.server.persistence.storageObjects.Interest;
import ie.dkit.semanticPhotoWeb.server.persistence.storageObjects.Person;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

public class FOAF {

	private RootElementFOAF rootElement = new RootElementFOAF();

	public void addPerson(PersonFOAF person) {
		rootElement.persons.add(person);
	}

	public void addInterests(PersonFOAF person, DescrpitionFOAF descrpition) {
		if (person.interest == null) {
			person.interest = new InterestFOAF();
		}
		person.interest.descrition.add(descrpition);
	}

	public void addKnownPerson(PersonFOAF person, PersonFOAF knowsPerson) {
		if (person.knows == null) {
			person.knows = new KnowsFOAF();
		}
		person.knows.persons.add(knowsPerson);
	}

	public void consumePerson(Person person) {
		InterestFOAF interests = new InterestFOAF();
		for (Interest interest : person.getInterests()) {
			interests.descrition.add(new DescrpitionFOAF(interest.getAbout(),
					interest.getTitle()));
		}
		if (interests.descrition.size() <= 0) {
			interests = null;
		}
		KnowsFOAF knows = new KnowsFOAF();
		for (Person known : person.getKnows()) {
			PersonFOAF personFOAF = new PersonFOAF();
			personFOAF.name = known.getName() == null ? new NameFOAF(known
					.getUsername()) : new NameFOAF(person.getName());
			personFOAF.xml = null;
			knows.persons.add(personFOAF);
		}
		if (knows.persons.size() <= 0) {
			knows = null;
		}
		NameFOAF nameFOAF = person.getName() == null ? null : new NameFOAF(
				person.getName());
		EmailFOAF emailFOAF = person.getEmail() == null ? null : new EmailFOAF(
				person.getEmail());
		HomepageFOAF homepageFOAF = person.getHomepage() == null ? null
				: new HomepageFOAF(person.getHomepage());
		NickFOAF nickFOAF = person.getNick() == null ? null : new NickFOAF(
				person.getNick());
		PhotoFOAF photoFOAF = person.getPhoto() == null ? null : new PhotoFOAF(
				person.getPhoto());
		rootElement.persons.add(new PersonFOAF(nameFOAF, emailFOAF,
				homepageFOAF, nickFOAF, photoFOAF, interests, knows));
	}

	public String toString() {
		StringWriter writer = new StringWriter();
		try {
			JAXBContext context = JAXBContext
					.newInstance(RootElementFOAF.class);
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			m.marshal(rootElement, writer);
			return writer.toString();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return "";
	}
}

@XmlRootElement(name = "rdf:RDF")
class RootElementFOAF {
	@XmlAttribute(name = "xmlns:rdf")
	public String rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";

	@XmlAttribute(name = "xmlns:foaf")
	public String foaf = "http://xmlns.com/foaf/0.1/";

	@XmlAttribute(name = "xmlns:dc")
	public String dc = "http://purl.org/dc/elements/1.1/";

	@XmlAttribute(name = "xmlns:rdfs")
	public String rdfs = "http://www.w3.org/2000/01/rdf-schema#";

	@XmlElement(name = "foaf:Person")
	public List<PersonFOAF> persons = new ArrayList<PersonFOAF>();
}

class PersonFOAF {
	@XmlAttribute(name = "xml:lang")
	public String xml = "en";

	@XmlElement(name = "foaf:name")
	public NameFOAF name;

	@XmlElement(name = "foaf:mbox")
	public EmailFOAF email;

	@XmlElement(name = "foaf:homepage")
	public HomepageFOAF homepage;

	@XmlElement(name = "foaf:nick")
	public NickFOAF nick;

	@XmlElement(name = "foaf:depiction")
	public PhotoFOAF photo;

	@XmlElement(name = "foaf:interest")
	public InterestFOAF interest;

	@XmlElement(name = "foaf:knows")
	public KnowsFOAF knows;

	public PersonFOAF() {

	}

	public PersonFOAF(NameFOAF name, EmailFOAF email, HomepageFOAF homepage,
			NickFOAF nick, PhotoFOAF photo, InterestFOAF interest,
			KnowsFOAF knows) {
		super();
		this.name = name;
		this.email = email;
		this.homepage = homepage;
		this.nick = nick;
		this.photo = photo;
		this.interest = interest;
		this.knows = knows;
	}

}

class NameFOAF {
	@XmlValue
	public String name;

	public NameFOAF() {

	}

	public NameFOAF(String name) {
		this.name = name;
	}
}

class EmailFOAF {
	@XmlAttribute(name = "rdf:resource")
	public String resource;

	public EmailFOAF() {
	}

	public EmailFOAF(String resource) {
		this.resource = "mailto:" + resource;
	}
}

class HomepageFOAF {
	@XmlAttribute(name = "rdf:resource")
	public String resource;

	public HomepageFOAF() {
	}

	public HomepageFOAF(String resource) {
		this.resource = resource;
	}
}

class NickFOAF {
	@XmlValue
	public String name;

	public NickFOAF() {
	}

	public NickFOAF(String name) {
		this.name = name;
	}
}

class PhotoFOAF {
	@XmlAttribute(name = "rdf:resource")
	public String resource;

	public PhotoFOAF() {
	}

	public PhotoFOAF(String resource) {
		this.resource = resource;
	}
}

class InterestFOAF {
	@XmlElement(name = "rdf:Description")
	public List<DescrpitionFOAF> descrition = new ArrayList<DescrpitionFOAF>();
}

class DescrpitionFOAF {
	@XmlAttribute(name = "rdf:about")
	public String about;

	@XmlElement(name = "dc:title")
	public String title;

	public DescrpitionFOAF() {
	}

	public DescrpitionFOAF(String about, String title) {
		this.about = about;
		this.title = title;
	}
}

class KnowsFOAF {
	@XmlElement(name = "foaf:Person")
	public List<PersonFOAF> persons = new ArrayList<PersonFOAF>();
}